﻿using FFmpegDecodecVideo.AttributeUsageFolder;
using FFmpegDecodecVideo.FFmpegUlit;
using Microsoft.Graphics.Canvas;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Graphics.DirectX;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace FFmpegDecodecVideo.Views
{
    [PageInfoAttibute("解码视频")]
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public unsafe sealed partial class FFmpegDecodecVideo : Page
    {
        Task PlayTask;
        CanvasBitmap bitmap;
        DispatcherTimer timer = new DispatcherTimer();
        bool progressActivity = false;
        DecodecVideo video = new DecodecVideo();
        public FFmpegDecodecVideo()
        {
            this.InitializeComponent();
            Init();
            InitUi();
        }
        void Init()
        {
            //播放
            play.Click += (s, e) =>
            {
                if (video.State == MediaState.None)
                {
                    //初始化解码视频
                    video.InitDecodecVideo(pathBox.Text);
                    DisplayVideoInfo();
                }
                video.Play();
                timer.Start();
            };
            //暂停
            pause.Click += (s, e) => video.Pause();
            stop.Click += (s, e) => video.Stop(); ;
            PlayTask = new Task(() =>
            {
                while (true)
                {
                    //播放中
                    if (video.IsPlaying)
                    {
                        //获取下一帧视频
                        if (video.TryReadNextFrame(out var frame))
                        {
                            var bytes = video.FrameConvertBytes(&frame);
                            bitmap = CanvasBitmap.CreateFromBytes(CanvasDevice.GetSharedDevice(), bytes, video.FrameWidth, video.FrameHeight, DirectXPixelFormat.B8G8R8A8UIntNormalized);
                            canvas.Invalidate();
                        }
                    }
                }
            });
            PlayTask.Start();
            video.MediaCompleted += (s) =>
            {
                DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
                {
                    timer.Stop();
                    progressActivity = false;
                    DisplayVideoInfo();
                });
            };
        }
        void InitUi()
        {
            //画布绘制
            canvas.Draw += (s, e) =>
            {
                if (bitmap != null)
                {
                    var te = Win2DUlit.CalcutateImageCenteredTransform(canvas.ActualSize, bitmap.Size);
                    te.Source = bitmap;
                    e.DrawingSession.DrawImage(te);
                }
            };
            timer.Interval = TimeSpan.FromMilliseconds(300);
            //计时器更新进度条
            timer.Tick += (s, e) =>
            {
                if (!video.IsPlaying)
                    return;
                position.Text = video.Position.ToString();
                progressActivity = false;
                progress.Value = video.Position.TotalSeconds;
                progressActivity = true;
            };
            //进度条更改
            progress.ValueChanged += (s, e) =>
            {
                if (!video.IsPlaying)
                    return;
                if (progressActivity == true)
                {
                    video.SeekProgress((int)e.NewValue);
                }
            };
        }

        /// <summary>
        /// 显示视频信息
        /// </summary>
        void DisplayVideoInfo()
        {
            dura.Text = video.Duration.ToString();
            videoCodec.Text = video.CodecName;
            videoBitrate.Text = video.Bitrate.ToString();
            videoWidth.Text = video.FrameWidth.ToString();
            videoHeight.Text = video.FrameHeight.ToString();
            videoFps.Text = video.FrameRate.ToString();
            duration.Text = video.Duration.ToString();
            position.Text = video.Position.ToString();
            progress.Maximum = video.Duration.TotalSeconds;
        }
    }
}
